//
// Created by 86134 on 2024/1/18.
//

#ifndef BASE_DEFIND_H
#define BASE_DEFIND_H


/**
 * 
 * usually use 
 */
///
/// BASE
///
#define DISABLE_CONSTUCTOR(T)                       \
    T() = delete;                                   \
    ~T() = delete

#define DISABLE_COPY(T)                             \
    T(const T&) = delete;                           \
    T& operator=(const T&) = delete

#define DISABLE_MOVE(T)                            \
    T(T &&) = delete;                               \
    T& operator=(T&&) = delete

#define DEFAULT_COPY(T)                             \
    T(const T &) = default;                         \
    T& operator=(const T&) = default

#define DEFAULT_MOVE(T)                             \
    T(T&&) = default;                               \
    T& operator=(T&&) = default

#define DEFAULT_NULL_CONSTUCTOR(T)                  \
    T() = default;                                  \
    ~T() = default

///
/// USE
///
#define DELETE_CONSTRUCTOR(T)                       \
    DISABLE_CONSTUCTOR(T);                          \
    DISABLE_COPY(T);                                \
    DISABLE_MOVE(T)     

#define NOTCOPY_CONSTRUCTOR(T)                      \
    DISABLE_COPY(T);                                \
    DISABLE_MOVE(T)     

#define NONCOPY_NONMOVE_CONSTRUCTOR(T)              \
    DISABLE_COPY(T);                                \
    DISABLE_MOVE(T)

#define DEFAULT_CONSTRUCTOR(T)                      \
    DEFAULT_COPY(T);                                \
    DEFAULT_MOVE(T)

// ֻ���ƶ����첻�ܿ�������
#define MOVE_NONCOPY_CONSTRUCTOR(T)                 \
    DEFAULT_MOVE(T);                                \
    DISABLE_COPY(T)

/* Connection.cpp/Connection.h */
#include <cstdio>
enum SOCKET_STATUS{
    // the connection is not used 
    UNUSE= 0,        
    // the connection has bnding a socket fd
    OPENING,        
    // connection is call the connect() or accept() 
    // and establish a connection with removed address
    CONNECTED,
    // conneciont call bind() and listen() success
    // and listening to the given port
    LISTENING,
    // conneciont call the close() 
    // and ready to be putted back the connection pool(a object pool)
    CLOSED,
};


/* Scoket.cpp/Scoekt.h */
#define BACKLOG 20          // the listen queue length -> backlog

/* Reactor.h/Reactor.cpp */
#define CONNCTION_MAX 1000
#define REACTOR_NUM 1
enum reactor_status {
    REACTOR_RUNING,
    REACTOR_FREE,
};


/* Dispatch.h/Dispatch.cpp */
enum dispatch_status {
    RUNING = 0,
    FREE,
};


/* Buffer.h/Buffer.cpp */
#define SHORT_MAX       32767
#define BUFFER_SIZE 512
#define HEAD_LEN 2
#define UUID_LEN 16
enum DATA_STATUS {
    HEAD_LACK,
    DATA_LACK,
    UUID_LACK,
};


/* MemoryPool.h/MemoryPool.cpp */
#define MEMORY_POOL_BLOCK_NUM       100    // the num of memorypage
#define MEMORY_POOL_BLOCK_SIZE      512    // the size of memoryblock
#define MEMORY_POOL_PAGE_SIZE       1      // the size of memory page in the pool when init


/* ThreadPool.h/ThreadPool.cpp */
#define THREAD_POOL_SIZE            1       // how many thread are there in the thread pool

/* ObjectPool.h/ObjectPool.cpp */
enum POOL_USAGE {
    STORTAGE,
    MODERATION,
    EASY,
};
#define OBJECT_STORAGE              0.85
#define OBJECT_MODERATION           0.75
#define OBJECT_EASY                 0.60
#define OBJECT_POOL_DEFINE_NUM      100


// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// Database 
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------

/* Alloc.h/Alloc.cpp */
#define PAGE_TYPE_NUM               9
// the size of the memory pool(alloc paeg) 
#define PAGE_SIZE_8                 8
#define PAGE_SIZE_16                16
#define PAGE_SIZE_32                32
#define PAGE_SIZE_64                64
#define PAGE_SIZE_128               128
#define PAGE_SIZE_256               256
#define PAGE_SIZE_512               512
#define PAGE_SIZE_1024              1024
#define PAGE_SIZE_2048              2048

enum page_size_index {
    INDEX_SIZE_8,
    INDEX_SIZE_16,
    INDEX_SIZE_32,
    INDEX_SIZE_64,
    INDEX_SIZE_128,
    INDEX_SIZE_256,
    INDEX_SIZE_512,
    INDEX_SIZE_1024,
    INDEX_SIZE_2048,
};

// the min blocks a page need to have
#define BLOCK_BASIC                 10
// calculate how much blocks do a variable page need
#define BLOCK_NUM(n, size)  \
if (n == PAGE_SIZE_2048) size = BLOCK_BASIC;    \
else if (n > 96) size = ((n - 96) / 96 + 1) * BLOCK_BASIC * 10; \
else size = ((96 - n) / 96 + 1) * BLOCK_BASIC * 10

// judge the size
#define GUDGE_LEVEL_OF_SIZE(size, level)                \
if (size > PAGE_SIZE_1024) level = INDEX_SIZE_2048;     \
else if (size > PAGE_SIZE_512) level = INDEX_SIZE_1024; \
else if (size > PAGE_SIZE_256) level = INDEX_SIZE_512;  \
else if (size > PAGE_SIZE_128) level = INDEX_SIZE_256;  \
else if (size > PAGE_SIZE_64) level = INDEX_SIZE_128;   \
else if (size > PAGE_SIZE_32) level = INDEX_SIZE_64;    \
else if (size > PAGE_SIZE_16) level = INDEX_SIZE_32;    \
else if (size > PAGE_SIZE_8) level = INDEX_SIZE_16;     \
else level = INDEX_SIZE_8

#define CALCULATE_SIZE(size, true_sizes)                \
if (size > PAGE_SIZE_1024) true_sizes = PAGE_SIZE_2048;     \
else if (size > PAGE_SIZE_512) true_sizes = PAGE_SIZE_1024; \
else if (size > PAGE_SIZE_256) true_sizes = PAGE_SIZE_512;  \
else if (size > PAGE_SIZE_128) true_sizes = PAGE_SIZE_256;  \
else if (size > PAGE_SIZE_64) true_sizes = PAGE_SIZE_128;   \
else if (size > PAGE_SIZE_32) true_sizes = PAGE_SIZE_64;    \
else if (size > PAGE_SIZE_16) true_sizes = PAGE_SIZE_32;    \
else if (size > PAGE_SIZE_8) true_sizes = PAGE_SIZE_16;     \
else true_sizes = PAGE_SIZE_8

/* Skiplist.h/Skiplist.cpp */

#define SKIPLIST_MEX_LEVEL  32
#define SKIPLIST_P          0.25


/* Tool.h / Tool.cpp */
#define COMMAND_TYPE        0
#define COMMAND_KEY         1
#define COMMAND_VALUE       2

/* Object.h/Object.cpp */
// be use to sign the goal type of the object
#define STRING_TYPE     1
#define HASH_TYPE       2
#define LIST_TYPE       3
#define SET_TYPE        4
#define ZSET_TYPE       5

// command excute success 
#define OK          "OK"    // when the command without return value
#define NIL         "nil"   // command excute error

/* StringObject.h / StringObject.cpp */
#define SCOMPARE_TRUE       "TRUE"
#define SCOMPARE_FALSE      "FALSE"
#define SAPPEND_NULL        "the argument is nullptr!"

/* SetObject.h / SetObject.cpp */
#define SADD_SUCCESS        "fault! Because the element is exist!"
#define SEXIT_TRUE          "exist!"
#define SEXIT_FALSE         "not exist!"
#define SPOP_SUCCESS        "success!"
#define SPOP_FAULT          "the element is not in the object!"

/* HashObject.h / HashObject.cpp */
#define HADD_FAULT      "the key is already exist!"
#define HEXIST_FAULT    "null!"
#define HREMOVE_FAULT   "the specified element is not exist!"

/* ListObject.h / ListObject.cpp*/
#define LISTOBJECT_LEN          "size : "
#define LINDEX_OUT_OF_RANGE     "index out of range!"
#define LINSERT_SUCCESS(index, \
new_value)                      ( "INDEX " + index + " : " + new_value) 
#define LINSERT_FAULT           "index out of range!"
#define LREMOVE_FAULT           "index out of range!"
#define LSET_SUCCESS(index, \
new_value)                      ( "INDEX " + index + " : " + new_value) 
#define LSET_FAULT              "index out of range!"
#define LTRIM_NUM(num)          ("remove number : " + num)

/* ZsetObject.h / ZsetObject.cpp */
#define ZSETOBJECT_ZADD_DEFAULT     "the element is exist!"
#define ZSETOBJECT_INPUT_ILLEGAL    "you input is illegal!"
#define ZSETOBJECT_ZRAND_DEFAULT    "specified element is not in the object!"
#define ZSETOBJECT_ZSCORE_DEFAULT   "the element has this score is not exist!"
#define ZSETOBJECT_ZREMOVE_DEFAULT  ZSETOBJECT_ZSCORE_DEFAULT

/* Aof.h / Aof.cpp */
#define AOF_FILE_MAX        1024 * 6    // default : 1024 * 1024
#define AOF_FILE            "db.aof"
#define AOF_INCR            "incr.aof"
#define AOF_BASE            "base.aof"
#define AOF_BUF_SIZE        1024 * 4    // default : 1024
                                        // user can motify this parma dynamically
#define AOF_IS_START        1           // default open the aof machainal to save to data
                                        // but user can clear the flag to close it
#define AOFRW_FIN_SIG       "f"
#define AOFRW_FIN_LEN       1

/* Excutor.h / Excutor.cpp */
#define TIMEOUT             "nil"
#define KEY_NONEXIT         TIMEOUT

enum EXCUTOR_ERR {
    ERR_TIMEOUT = 1,
    ERR_NONEXIT_CREAT,
    ERR_NORMAL,
    ERR_NONEXIT_RET,
};

// COMMEN COMMAND 
// ���������еĶ��������
#define TTL     1
#define TYPE    2
#define ALIVE   3

#define COMMAND_GET         0

// HahsObject 
#define COMMAND_HADD        1
#define COMMAND_HSIZE       2
#define COMMAND_HEXIST      3
#define COMMAND_HREMOVE     4

// ListObject
#define COMMAND_LPUSH       1
#define COMMAND_RPUSH       2
#define COMMAND_LPOP        3
#define COMMAND_RPOP        4
#define COMMAND_LINDEX      5
#define COMMAND_LLEN        6
#define COMMAND_LINSERT     7
#define COMMAND_LREMOVE     8
#define COMMAND_LSET        9
#define COMMAND_LTRIM       10

// SetObject
#define COMMAND_SADD        1
#define COMMAND_SSIZE       2
#define COMMAND_SEXIST      3
#define COMMAND_SPOP        4
#define COMMAND_SGET        5

// StringObject
#define COMMAND_SAPPEND     1
#define COMMAND_SET         2
#define COMMAND_SCOMPARE    3
#define COMMAND_SCLEAR      4
#define COMMAND_SLEN        5

// ZsetObject
#define COMMAND_ZADD        1
#define COMMAND_ZLEN        2
#define COMMAND_ZCOUNT      3
#define COMMAND_ZRANK       4
#define COMMAND_ZSCORE      5
#define COMMAND_ZREMOVE     6

/**
 * 
 * Buffer.hpp / Buffer.cpp
 */
#define LOGGER_BUFFER_SIZE 1024

/**
 * 
 * Buffer.hpp / Buffer.cpp
 */
#define LOGGER_BUFFER_SIZE 1024

/**
 * --------------------------------------------------------------
 * --------------------------------------------------------------
 * --------------------------------------------------------------
 * 
 * Timer
 * 
 * --------------------------------------------------------------
 * --------------------------------------------------------------
 * --------------------------------------------------------------
*/

/* TimingHeap.h / TimingHeap.cpp */
#define HEAP_SIZE   10
#define HEAP_DILATATION     2


// log file name
#define LOG_FILE_NAME "db_log.txt"


/**
 * --------------------------------------------------------------
 * --------------------------------------------------------------
 * --------------------------------------------------------------
 * 
 * Coroutine
 * 
 * --------------------------------------------------------------
 * --------------------------------------------------------------
 * --------------------------------------------------------------
*/
// 协程栈的大小
#define FIBER_STACK_SIZE    1024 * 128

// 在hook io中的tcp连接超时的时间
#define TCP_CONNECT_TIMEOUT 5000

#endif //SOCKET_DEFIND_H